// SIPMessage.h: interface for the CSIPMessage class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_SIPMESSAGE_H__B09EA9FD_B914_4F6C_B291_209B9E116849__INCLUDED_)
#define AFX_SIPMESSAGE_H__B09EA9FD_B914_4F6C_B291_209B9E116849__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#pragma warning(disable:4786)

#include "base.h"

#include "public.h"
#include "Transport.h"
#include "SIPHeader.h"
#include "osplatform.h"
#include "mystring.h"
#include <list>

#define		MSG_NULL		0
#define		MSG_REQUEST		1
#define		MSG_RESPONSE	2
typedef std::list<CSIPVia *>  CSIPVias;
typedef std::list<CSIPContact*>	CSIPContacts;
typedef std::list<CSIPContact*>::iterator CSIPContactsItem;
typedef std::list<CSIPAccept *> CSIPAccepts;
typedef std::list<CSIPAccept *>::iterator CSIPAcceptsItem;
typedef std::list<CSIPAllow *>	CSIPAllows;
typedef std::list<CSIPAllow *>::iterator  CSIPAllowsItem;
typedef std::list<CSIPAllowEvents *> CSIPAllowEventsList;
typedef std::list<CSIPAllowEvents *>::iterator CSIPAllowEventsItem;
typedef std::list<CSIPContentEncoding *> CSIPContentEncodings;
typedef std::list<CSIPContentEncoding *>::iterator CSIPContentEncodingsItem;
typedef std::list<CSIPContentLanguage *> CSIPContentLanguages;
typedef std::list<CSIPContentLanguage *>::iterator  CSIPContentLanguagesItem;
typedef std::list<CSIPRequire *> CSIPRequires;
typedef std::list<CSIPRequire *>::iterator	CSIPRequiresItem;
typedef std::list<CSIPSupported *> CSIPSupporteds;
typedef std::list<CSIPSupported *>::iterator CSIPSupportedsItem;

typedef std::list<CSIPRoute *>	CSIPRoutes;
typedef std::list<CSIPRoute *>::iterator	CSIPRoutesItem;
typedef std::list<CSIPAcceptEncoding *>	CSIPAcceptEncodings;
typedef std::list<CSIPAcceptEncoding *>::iterator	CSIPAcceptEncodingsItem;
typedef std::list<CSIPAcceptLanguage *>	CSIPAcceptLanguages;
typedef std::list<CSIPAcceptLanguage *>::iterator	CSIPAcceptLanguagesItem;
typedef std::list<CSIPNATAddress *> CSIPNATAddresses;
typedef std::list<CSIPNATAddress *>::iterator CSIPNATAddressesItem;
//#ifdef PC_CLIENT
typedef std::list<CSIPUnsupported *> CSIPUnsupporteds;
typedef std::list<CSIPUnsupported *>::iterator CSIPUnsupportedsItem;
typedef std::list<CSIPProxyRequire *> CSIPProxyRequires;
typedef std::list<CSIPProxyRequire *>::iterator CSIPProxyRequiresItem;
typedef std::list<CSIPWarning *> CSIPWarnings;
typedef std::list<CSIPWarning *>::iterator CSIPWarningsItem;
typedef std::list<CSIPErrorInfo *>	CSIPErrorInfos;
typedef std::list<CSIPCallInfo *>	CSIPCallInfos;
typedef std::list<CSIPAuthenticationInfo *>	CSIPAuthenticationInfos;
typedef std::list<CSIPAlertInfo *>	CSIPAlertInfos;
//#endif

class CTransaction; //yb added 20100203
class BASE_API CSIPMessage  
{
public:
	struct DestinationInfo{
		CTransport::TYPE	transport;
		mystring			ip;
		int					port;
	};
	CSIPRoutes &RecordRoutes(){return m_RecordRoutes;};
	CSIPRoutes &RecordRouteList(){return m_RecordRoutes;};
	CSIPRoutes &Routes(){return m_Routes;};
	CSIPRoutes &RouteList(){return m_Routes;};
	CSIPAllows &Allows(){return m_Allows;};
	CSIPMaxForwards &MaxForwards();
	CSIPSequence &Sequence();
	CSIPSequence &CSeq();
	CSIPContacts &Contacts(){return m_Contacts;};
	CSIPContacts &ContactList(){return m_Contacts;};
	CSIPCallID &CallId();
	CSIPRequestLine &RequestLine();
	CSIPStatusLine &StatusLine();
	CSIPVias &Vias(){return m_Vias;};
	CSIPVias &ViaList(){return m_Vias;};
//	CSIPSupportedList &SupportedList(){return m_SupportedList;};
	CSIPTo &To();
	CSIPFrom &From();
	CSIPTranslate &Translate();
	CSIPExpires &Expires();
	CSIPMinExpires &MinExpires();
	CSIPEvent &Event();
	CSIPAllowEventsList &AllowEvents(){return m_AllowEvents;};
	CSIPAccepts &Accepts(){return m_Accepts;};
	CSIPAcceptEncodings &GetAcceptEncodings(){return m_AcceptEncodings;};
	CSIPAcceptLanguages &GetAcceptLanguages(){return m_AcceptLanguages;};
	CSIPContentType &ContentType();
	CSIPContentLength &ContentLength();
	CSIPContentEncodings &ContentEncodings(){return m_ContentEncodings;};
	CSIPContent &Content();
	CSIPContentDisposition &ContentDisposition();
	CSIPUserAgent &UserAgent();
	list<CSIPUnknown *> &Unknown(){return m_UnknownHeaders;};
	CSIPRequires &Requires(){return m_Requires;};

	
	CSIPSubscriptionState &SubscriptionState();
	CSIPDate &Date();
	
	
	CSIPMIMEVersion &MIMEVersion();
	CSIPAuthorization &Authorization();
	CSIPProxyAuthorization &ProxyAuthorization();
	CSIPProxyAuthenticate &ProxyAuthenticate();
	CSIPWWWAuthenticate &WWWAuthenticate();
	CSIPNATAddresses &NATAddresses(){return m_NATAddresses;};


//#ifdef PC_CLIENT
	CSIPAuthenticationInfos &AuthenticationInfos(){return m_AuthenticationInfos;};
	CSIPAlertInfos &AlertInfos(){return m_AlertInfos;};
	CSIPProxyRequires &ProxyRequireList(){return m_ProxyRequires;};
	CSIPSupporteds &Supporteds(){return m_Supporteds;};
	CSIPUnsupporteds &Unsupporteds(){return m_Unsupporteds;};
	CSIPProxyRequires &ProxyRequires(){return m_ProxyRequires;};

	CSIPServer &Server();
	CSIPInReplyTo &InReplyTo();
	CSIPOrganization &Organization();
	CSIPPriority &Priority();
	CSIPErrorInfos &ErrorInfos(){return m_ErrorInfos;};
	CSIPReplyTo &ReplyTo();
	CSIPRetryAfter &RetryAfter();
	CSIPSubject &Subject();
	CSIPTimestamp &Timestamp();
	CSIPWarnings &Warnings(){return m_Warnings;};
	CSIPCallInfos &CallInfos(){return m_CallInfos;};
	CSIPWebAddress &WebAddress();
	CSIPSNTPAddress &SNTPAddress();
	CSIPFileName &FileName();
	CSIPScale &Scale();
	CSIPSeek &Seek();
//#endif
	const CSIPRoutes* GetRecordRoutes()const {return &m_RecordRoutes;};
	const CSIPRoutes* GetRecordRouteList()const {return &m_RecordRoutes;};
	const CSIPRoutes* GetRoutes()const {return &m_Routes;};
	const CSIPRoutes* GetRouteList()const {return &m_Routes;};
	const CSIPAllows	*GetAllows()const {return &m_Allows;};
	const CSIPUserAgent *GetUserAgent()const {return m_pUserAgent;};
	const CSIPContent *GetContent()const{return m_pContent;};
	const CSIPRequestLine *GetRequestLine()const{return m_pRequestLine;};
	const CSIPStatusLine *GetStatusLine()const{return m_pStatusLine;};
	const CSIPTo *GetTo()const{return m_pTo;};
	const CSIPFrom *GetFrom()const{return m_pFrom;};
	const CSIPContacts &GetContacts()const{return m_Contacts;};
	const CSIPContacts *GetContactList()const{return &m_Contacts;};
	const CSIPTranslate *GetTranslate()const {return m_pTranslate;};
	const CSIPCallID *GetCallId()const {return m_pCallID;};
	const CSIPExpires *GetExpires()const{return m_pExpires;};
	const CSIPMinExpires *GetMinExpires()const{return m_pMinExpires;};
	const CSIPMaxForwards *GetMaxForwards()const{return m_pMaxForwards;};
	const CSIPSequence* GetSequence()const{return m_pSequence;};
	const CSIPSequence* GetCSeq()const{return m_pSequence;};
	const CSIPVias &GetVias()const{return m_Vias;};
	const CSIPVias *GetViaList()const{return &m_Vias;};
	const CSIPEvent *GetEvent()const {return m_pEvent;};
	const CSIPAllowEventsList* GetAllowEvents()const{return &m_AllowEvents;};
	const CSIPAccepts *GetAccepts()const{return &m_Accepts;};
	const CSIPAcceptEncodings *GetAcceptEncodings()const{return &m_AcceptEncodings;};
	const CSIPAcceptLanguages *GetAcceptLanguages()const{return &m_AcceptLanguages;};
	const CSIPContentType *GetContentType()const{return m_pContentType;};
	const CSIPContentEncodings *GetContentEncoding()const {return &m_ContentEncodings;};
	const CSIPContentLanguages *GetContentLanguages()const{return &m_ContentLanguages;};
	const CSIPContentLength *GetContentLength()const{return m_pContentLength;};

	

	const list<CSIPUnknown *> *GetUnknown()const{return &m_UnknownHeaders;};
	const CSIPRequires* GetRequires()const {return &m_Requires;};
	const CSIPSubscriptionState *GetSubscriptionState()const{return m_pSubscriptionState;};
	const CSIPDate *GetDate()const{return m_pDate;};


	const CSIPAuthorization *GetAuthorization()const{return m_pAuthorization;};
	const CSIPProxyAuthorization *GetProxyAuthorization()const{return m_pProxyAuthorization;};
	const CSIPProxyAuthenticate *GetProxyAuthenticate()const{return m_pProxyAuthenticate;};
	const CSIPWWWAuthenticate *GetWWWAuthenticate()const{return m_pWWWAuthenticate;};
	
	const CSIPMIMEVersion *GetMIMEVersion()const{return m_pMIMEVersion;};
	const CSIPNATAddresses *GetNATAddresses()const{return &m_NATAddresses;};
//#ifdef PC_CLIENT
	const CSIPAuthenticationInfos *GetAuthenticationInfos()const{return &m_AuthenticationInfos;};
	const CSIPProxyRequires *GetProxyRequireList()const{return &m_ProxyRequires;};
	const CSIPProxyRequires *GetProxyRequires()const{return &m_ProxyRequires;};
	const CSIPAlertInfos *GetAlertInfos()const {return &m_AlertInfos;};
	const CSIPContentDisposition *GetContentDisposition()const{return m_pContentDisposition;};
	const CSIPUnsupporteds *GetUnsupporteds()const{return &m_Unsupporteds;};
	const CSIPSupporteds *GetSupported()const{return &m_Supporteds;};
	const CSIPServer *GetServer()const{return m_pServer;};
	const CSIPPriority *GetPriority()const{return m_pPriority;};
	const CSIPOrganization *GetOrganization()const {return m_pOrganization;};
	const CSIPErrorInfos *GetErrorInfos(){return &m_ErrorInfos;};
	const CSIPInReplyTo *GetInReplyTo()const{return m_pInReplyTo;};
	const CSIPReplyTo *GetReplyTo()const{return m_pReplyTo;};
	const CSIPRetryAfter *GetRetryAfter()const{return m_pRetryAfter;};
	const CSIPSubject *GetSubject()const{return m_pSubject;};
	const CSIPTimestamp *GetTimestamp()const{return m_pTimestamp;};
	const CSIPWarnings *GetWarnings()const{return &m_Warnings;};
	const CSIPCallInfos *GetCallInfos()const{return &m_CallInfos;};
	const CSIPWebAddress *GetWebAddress()const{return m_pWebAddress;};
	const CSIPSNTPAddress *GetSNTPAddress()const{return m_pSNTPAddress;};
	const CSIPFileName* GetFileName()const{return m_pFileName;};
	const CSIPScale* GetScale(){return m_pScale;};
	const CSIPSeek* GetSeek(){return m_pSeek;};
//#endif

	void RemoveContent();
	MethodTypes GetMethod()const;
	bool IsRequest()const{return m_nType == MSG_REQUEST;};
	bool IsResponse()const{return m_nType == MSG_RESPONSE;};
	mystring &GetTransactionID(){return m_strTransactionID;};
	const mystring &GetTransactionID()const{return m_strTransactionID;};
	void SetTransactionID(const mystring &id){m_strTransactionID = id;};
	int GetError(){return m_nError;};
	int Parse(const char *pbuf,int len);
	CSIPMessage();
	CSIPMessage(int type)
     {Init();
      m_nType = type;
      timeval tv;
	  gettimeofday(&tv, NULL);
      m_usProduceTime = tv.tv_sec * 1000 * 1000  +  tv.tv_usec;
    };
	CSIPMessage(const CSIPMessage &msg);
	CSIPMessage(const char*pbuf,int len);
	virtual ~CSIPMessage();
	CSIPMessage& operator=(const CSIPMessage& other);
public:
	void Clear();
	mystring Encoding();
	CTransport::Tuple		m_Source;
	CTransport::Tuple		m_Destination;
	list<DestinationInfo>	m_DestIPList;

    //yb added 20100203{
    int64                   m_usProduceTime; //the time sip is created
    int64                   m_usRequestTime;//only for response SIP msg, the time when request SIP Msg produce.
    CTransaction*           m_pTransaction;
    int                     m_stateMachine_Next;//after this message send out, the transaction state change to this
    //yb added 20100203}

protected:

	CSIPRequestLine*		m_pRequestLine;
	CSIPStatusLine*			m_pStatusLine;	
	CSIPVias				m_Vias;
	CSIPTo*				    m_pTo;
	CSIPFrom*	    		m_pFrom;
	
	CSIPSNTPAddress*		m_pSNTPAddress;
	CSIPNATAddresses		m_NATAddresses;
	CSIPRoutes				m_Routes;
	CSIPRoutes				m_RecordRoutes;
	CSIPCallID*				m_pCallID;
	CSIPSequence*			m_pSequence;
	CSIPAllows				m_Allows;
	
	CSIPExpires*			m_pExpires;
	CSIPMinExpires*			m_pMinExpires;
	CSIPMaxForwards*		m_pMaxForwards;
	CSIPContentType*		m_pContentType;
	CSIPContentLength*		m_pContentLength;
	CSIPContentEncodings	m_ContentEncodings;
	CSIPContentLanguages	m_ContentLanguages;
	CSIPRequires			m_Requires;
	CSIPContacts			m_Contacts;

	CSIPUserAgent*			m_pUserAgent;
	CSIPTranslate*			m_pTranslate;
	CSIPContent*			m_pContent;
	CSIPAccepts				m_Accepts;
	CSIPAcceptEncodings		m_AcceptEncodings;
	CSIPAcceptLanguages		m_AcceptLanguages;
	CSIPEvent*				m_pEvent;
	CSIPAllowEventsList 	m_AllowEvents;
	CSIPSubscriptionState*	m_pSubscriptionState;
	CSIPMIMEVersion*		m_pMIMEVersion;
	CSIPDate*				m_pDate;
	
	CSIPAuthorization*		m_pAuthorization;
	CSIPProxyAuthorization*	m_pProxyAuthorization;
	CSIPProxyAuthenticate*	m_pProxyAuthenticate;
	CSIPWWWAuthenticate*	m_pWWWAuthenticate;
	CSIPFileName*			m_pFileName;
//#ifdef PC_CLIENT
	CSIPAuthenticationInfos	m_AuthenticationInfos;
	CSIPUnsupporteds		m_Unsupporteds;
	CSIPSupporteds			m_Supporteds;
	
	CSIPProxyRequires		m_ProxyRequires;
	CSIPPriority*			m_pPriority;
	CSIPServer*				m_pServer;
	CSIPAlertInfos			m_AlertInfos;
	CSIPErrorInfos			m_ErrorInfos;
	CSIPCallInfos			m_CallInfos;
	CSIPContentDisposition*	m_pContentDisposition;
	CSIPOrganization*		m_pOrganization;
	CSIPInReplyTo*			m_pInReplyTo;
	CSIPReplyTo*			m_pReplyTo;
	CSIPRetryAfter*			m_pRetryAfter;
	CSIPSubject*			m_pSubject;
	CSIPTimestamp*			m_pTimestamp;	
	CSIPWarnings			m_Warnings;
	CSIPWebAddress*			m_pWebAddress;
	CSIPScale*				m_pScale;
	CSIPSeek*				m_pSeek;
//#endif
	list<CSIPUnknown *>		m_UnknownHeaders;
private:
	void Init();
	int ParseVia(const char *pbuf,int len);
	int ParseContact(const char *pbuf,int len);
	int ParseContentEncoding(const char *pbuf,int len);
	int ParseAllowEvents(const char *pbuf,int len);
	int ParseAcceptEncoding(const char *pbuf,int len);
	int ParseAcceptLanguage(const char *pbuf,int len);
	int ParseNATAddress(const char *pbuf,int len);
	int ParseAllow(const char *pbuf,int len);
	int ParseContentLanguage(const char *pbuf,int len);
	int ParseRequire(const char *pbuf,int len);
	void eee1(const CSIPMessage& other);
private:
	int		m_nType;
	int		m_nError;
	mystring	m_strTransactionID;
};

#endif // !defined(AFX_SIPMESSAGE_H__B09EA9FD_B914_4F6C_B291_209B9E116849__INCLUDED_)
